from functools import total_ordering

from utils.log import Log
from utils.raw_obj import RawObject as Obj


class TreeNode(Log):
    def __init__(self, val):
        super(TreeNode, self).__init__()
        self.val = val
        self.left = None
        self.right = None
        self.parent = None

    def __repr__(self):
        return f"{self.__class__.__name__} {self.val}"

    # def __hash__(self):
    #     return hash(self.val)

    def __int__(self):
        return int(self.val.val if isinstance(self.val, Obj) else self.val)


@total_ordering
class BSTreeNode(TreeNode):
    def __lt__(self, other):
        if isinstance(other, self.__class__):
            return self.val < other.val
        else:
            self.simple_error("Incorrect attribute!")

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.val == other.val
        else:
            self.simple_error("Incorrect attribute!")

    def __hash__(self):
        # 在 Python 中，__hash__ 方法不可继承的原因是为了避免潜在的哈希冲突和不一致性。
        # 当一个类继承自另一个类时，如果子类不重新定义 __hash__ 方法，那么它将继承父类的 __hash__ 方法。
        # 然而，子类的对象可能具有与父类对象不同的哈希值计算方式，这可能导致哈希冲突和不正确的字典操作。
        # 为了确保哈希的正确性和一致性，Python 要求子类在需要自定义哈希行为时重新定义 __hash__ 方法。
        # 这样可以根据子类的特定属性和逻辑来计算哈希值，避免继承父类的哈希方法可能带来的问题。
        return hash(self.val)


if __name__ == '__main__':
    n1 = TreeNode(1)
    n2 = TreeNode(1)
    print(n1 == n2)

    n1 = BSTreeNode(1)
    n2 = BSTreeNode(1)
    print(n1 == n2)

    print(list(set([n1, n2])))
